#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

#define CRW_IMPL
#include "parStr.h"
#include "cr.h"
#include "error.h"


struct scr {
  FILE * f;
  bool isStdIn;
  parStr el;
  bool arr;
};

void readWhites(FILE *f);

cr
cr_create(char * f){
  cr c;

  assert(f != NULL);

  c = NULL;

  c = (cr) malloc(sizeof(struct scr));

  if (c != NULL){

    c->el = NULL;
   
    c->arr = FALSE;

    if (f[0] == '\0'){
      warnx("cr_create use stdin"); 
      c->isStdIn = TRUE;
      c->f = stdin;
    } else {
      c->isStdIn = FALSE;
      c->f = fopen (f, "r");
    }    
    if (c->f == NULL){
      warn(ERRFMT,"cr_create",__LINE__);
      free(c);
      c = NULL;

    }
  }

  return c;
}

cr
cr_destroy(cr c){

  assert(c != NULL);
  assert(c->f != NULL);

  if (! c->isStdIn)
    fclose(c->f);

  c->f = NULL;

  if (c->el != NULL) 
    c->el = parStr_destroy(c-> el);
  

  free(c);
  c = NULL;
  
  return c;
}

void readWhites(FILE *f){
  fscanf(f,"%*[ \t\n]");
}

cr
cr_arr(cr c){
  assert(c != NULL);
  assert(c->f != NULL);
  assert(c->arr == FALSE);
  assert(c->el == NULL);

  c->arr = TRUE;

  readWhites(c->f);

  if (feof(c->f))
    c->el = NULL;
  else {
    c->el = parStr_fromStream(c->f);

    if (c->el == NULL){
      c = cr_destroy(c);
/*       warnx(ERRFMT,"cr_arr",__LINE__); */
    }
  }
  return  c;

}

cr
cr_av(cr c){
  assert(c != NULL);
  assert(c->f != NULL);
  assert(c->arr == TRUE);
  assert(c->el != NULL);

  c->el = parStr_destroy(c->el);

  readWhites(c->f);

  if (feof(c->f))
    c->el = NULL;
  else {
    c->el = parStr_fromStream(c->f);

    if (c->el == NULL){
      c = cr_destroy(c);
/*       warnx(ERRFMT,"cr_arr",__LINE__); */
    }
  }
  return  c;
}

elec
cr_elecor(const cr c){
  assert(c != NULL);
  assert(c->f != NULL);
  assert(c->arr == TRUE);
  assert(c->el != NULL);
  
  return parStr_clone(c->el);
}

bool
cr_fin(const cr c){
  assert(c != NULL);
  assert(c->f != NULL);
  assert(c->arr == TRUE);
  
  return (c->el == NULL);
}
